﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Reflection;

namespace TaskCleanerNS
{
    public partial class FormMain : Form
    {
        #region Members and Ctors
        //Our file reader
        StreamReader _sr;
        const string APP_TITLE = "WarNovSoft - Task Cleaner";
        const string FILE_NAME = "ProcessesToKill.txt";
        string[] processes;

        public FormMain()
        {
            InitializeComponent();
        } 
        #endregion

        #region Events

        private void FrmMain_Load(object sender, EventArgs e)
        {            
            tltAuto.SetToolTip(btnAuto, "A file called ProcessToKill.txt must be present in the same directory as this application");
            SetIcon();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (ofdMain.ShowDialog() == DialogResult.OK)
            {
                btnKill.Enabled = true;
                _sr = new StreamReader(ofdMain.OpenFile());
                FillList();
            }
            else
            {
                MessageBox.Show("File not uploaded", APP_TITLE);
                btnKill.Enabled = false;
            }
        }

        private void btnKill_Click(object sender, EventArgs e)
        {

            KillProcesses();
        }

        private void btnAuto_Click(object sender, EventArgs e)
        {
            if (File.Exists(FILE_NAME))
            {
                _sr = new StreamReader(FILE_NAME);
                FillList();
                KillProcesses();
            }
            else
            {
                MessageBox.Show("Invalid File. Please verifiy the file called ProcessToKill.txt is present in the same directory as this application", APP_TITLE);
            }
        } 
        #endregion

        #region CoreMethods
        /// <summary>
        /// Try to kill the procces and render a report
        /// </summary>
        private void KillProcesses()
        {

            List<ProcessStatus> ret = TaskCleaner.KillProcesses(new List<string>(processes));
            StringBuilder sb = new StringBuilder();

            var alive = ProcessFilter(ret, PStatus.Survivor);
            var missed = ProcessFilter(ret, PStatus.Missed);
            var killed = ProcessFilter(ret, PStatus.Dead);


            if (killed.Count() > 0)
                AddToReport(sb, killed, "Some processes were succesfully killed:\n\n");
            if (alive.Count() > 0)
                AddToReport(sb, alive, "Some processes couldn't be killed:\n\n");
            if (missed.Count() > 0)
                AddToReport(sb, missed, "Some processes weren't found:\n\n");

            rtbLog.Text = sb.ToString();
        }

        private IEnumerable<ProcessStatus> ProcessFilter(List<ProcessStatus> list, PStatus pStatus)
        {
            var ret =
                from process in list
                where process.Status == pStatus
                select process;
            return ret;
        }

        private void AddToReport(StringBuilder sb, IEnumerable<ProcessStatus> list, string header)
        {
            sb.Append(header);
            foreach (var a in list)
            {
                sb.Append(a.ProcessName + "\n");
            }
            sb.Append("================================\n\n");
        }

        private void FillList()
        {
            string content = _sr.ReadToEnd();
            rtbProcessToKil.Text = content;
            processes = content.Split('\n');
        }

        private void SetIcon()
        {
            Assembly currentAssembly = Assembly.GetExecutingAssembly();
            Icon = new System.Drawing.Icon(currentAssembly.GetManifestResourceStream("TaskCleanerNS.Clean.ICO"));
        } 
        #endregion
    }
}
